
package reporting;
import java.util.*;
import java.text.DateFormat;
import java.text.SimpleDateFormat;

import static util.ConstantCollection.*;
import util.*;

/**
 * @author Roman I.
 *
 */

public class ReportEngine{
	
	/**  */
	private static final ReportEngine INSTANCE = new ReportEngine();
	/**  */
	//private Date lastMsgDate;
    
	//private Message message;
		
	
	private HashMap dictReports = new HashMap();
	
	///**
	//* Internal variable. The flag a showing, what reporting mode (Single/Multiple) is used at present
	//*/
	//private Boolean singleMode;
	//private String lastId;
	
	private Util u = new Util();
	
	//For statistic
	/*
	*//**
	 * Checkpoint iterator. Used To count total number of all checkpoints.
	 *//*
	private Integer cpCnt;
	*//**
	 * Failed checkpoint iterator. Used to count total number of failed checkpoints.
	 *//*
	private Integer cpFailedCnt;
	*//**
	 * Passed checkpoint iterator. Used to count total number of passed checkpoints.
	 *//*
	private Integer cpPassedCnt;
	*//**
	 * Step iterator. Used to count total number of all steps in Test.
	 *//*
	private Integer stepCnt;
	*//**
	 * Passed step iterator. Used to count total number of passed steps in Test.
	 *//*
	private Integer stepPassedCnt;
	*//**
	 * Failed step iterator. Used to count total number of failed steps in Test.
	 *//*
	private Integer stepFailedCnt;
	*//**
	 * Warning step iterator. Used to count total number of warning steps in Test.
	 *//*
	private Integer stepWarningCnt;
	*//**
	 * Error event iterator. Used to count total number of error events.
	 *//*
	private Integer errorCnt;
	*//**
	 *Warning event iterator. Used to count total number of warning events. 
	 *//*
	private Integer warningCnt;
	*//**
	 * Keeps current test status.
	 *//*
	private String testStatus;
	*//**
	 * Indicates, whether test status has been changed during step or checkpoint.
	 *//*
	private Boolean isTestStatusChanged;*/
	
	private TestConfiguration tc = TestConfiguration.getInstance();
		
	
	
	private ReportEngine() {
		//Initialise variables
		//testStatus = "Passed";
		//isTestStatusChanged = false;
		//singleMode = true;
		
		//Create folder tree
		FileWork fw = FileWork.getInstance();
		
		if(!fw.existsFileOrDir("log")){
			fw.createDir("log");
		}
		
		String tempPath = "log/" + tc.getEnv("_testname") + "/";
		
		if(!fw.existsFileOrDir(tempPath)){
			fw.createDir(tempPath);
		}
		
		DateFormat dateFormat = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss");
        Date date = new Date();
        String datetime = dateFormat.format(date);
        tempPath = tempPath + datetime + "/";
       	
        
		if(!fw.existsFileOrDir(tempPath)){
			fw.createDir(tempPath);
		}
		tc.setEnv("_logpath", tempPath);
		
		//Add reports
		String [] temppair = null;
		String [] temp = null;
		temppair = tc.getEnv("appliedreports").split("\\;");
		if (temppair.length == 0){
			System.out.println("Please, set 'appliedreports' variable correctly in configuration file!");
		}
		
		for (int i = 0 ; i < temppair.length ; i++) {
		  temp = temppair[i].split("\\@");
		  if (temp.length == 2){
			  addReport(temp[0], temp[1]);
		  }  
		}		
	}
	/**
	 * @return
	 */
	public static ReportEngine getInstance() {
	      return INSTANCE;
	}
    
    /**
     * @param lastMsgDate
     */
    //public void setLastMsgDate(Date lastMsgDate){
    //  	this.lastMsgDate = lastMsgDate;
    //}
    
    //public Date getLastMsgDate(){
    //    return lastMsgDate;
    //}
    

	/**
	 * @return the message
	 */
	//private Message getMessage() {
	//	return message;
	//}
	
	/**
	 * @param message the message to set
	 */
	//private void setMessage(Message message) {
	//	this.message = message;
	//}

    /**
	 * @return the dictReports
	 */
	public HashMap getDictReports() {
		return dictReports;
	}
	/**
	 * @param dictReports the dictReports to set
	 */
	private void addElementToDictReports(String key, XReport value) {
		dictReports.put(key, value);
    }
	

	/*public void report(String messageType, Integer statusMessage, String header, String fullDescription, String errorId, Object objCapture){
		reportEx(messageType, statusMessage, header, fullDescription, "", errorId, objCapture);
	}
	
	public void singleReport(String reportID, String messageType, Integer statusMessage, String header, String fullDescription, String errorId, Object objCapture){
		singleReportEx(reportID, messageType, statusMessage, header, fullDescription, "", errorId, objCapture);
	}*/
 
    /**
     * @param messageType
     * @param statusMessage
     * @param header
     * @param fullDescriptions
     * @param erroId
     * @param objCapture
     */
 /*   private void reportEx(String messageType, Integer statusMessage, String header, String fullDescription, String expectedResult, String errorId, Object objCapture){
    	singleMode = false;

    	Map.Entry entry = null;
    	Iterator it = getDictReports().entrySet().iterator();
    	while(it.hasNext()){
             entry = (Map.Entry)it.next();
             singleReportEx(entry.getKey().toString(), messageType, statusMessage, header, fullDescription, expectedResult, errorId, objCapture);
        }

    	
    	
    	singleMode = true;
    	clearMessage();
    }*/
    

/*    *//**
     * @param reportID
     * @param messageType
     * @param statusMessage
     * @param header
     * @param fullDescriptiond
     * @param erroId
     *//*
    @SuppressWarnings("unchecked")
	private void singleReportEx(String reportID, String messageType, Integer statusMessage, String header, String fullDescription, String expectedResult, String errorId, Object objCapture){
    	
    	reportID = reportID.toLowerCase();
    	reportID = reportID.trim();
       	 
		if (getDictReports().containsKey(reportID)){
			if (getMessage() == null){
				generateMessage(messageType, statusMessage, header, fullDescription, expectedResult, errorId, objCapture);
			}

			XReport objReporter = (XReport) getDictReports().get(reportID);
		
			objReporter.report(getMessage());	

			if (singleMode){
				clearMessage();
			}
		}	
		else{
			
            //TODO "The '" & reportID & "' reportID was not found", "The '" & reportID & "' reportID was not found in iDictReports! " & vbCrLf & _
			//"Debug Info: " & vbCrLf & signature 		
            return;
		}
          
  
    }*/
    
    /**
     * @param typeReport
     * @param nameReport
     */
    public void addReport(String typeReport, String nameReport){
    	typeReport = typeReport.toLowerCase();
    	typeReport = typeReport.trim();
    	String key;
    	TemplateReport reporterX;
   		if (typeReport.contentEquals("html")){
   			key = typeReport.concat("_").concat(nameReport);   
			if(!getDictReports().containsKey(key)){
				reporterX = new HtmlReport(nameReport);
			}
			else{
				System.out.println("There is no this type");
				return;
			}
				
		}
		else if(typeReport.contentEquals("txt")){
				key = typeReport.concat("_").concat(nameReport);
				if(!getDictReports().containsKey(key)){
					reporterX = new TxtReport(nameReport);
				}
				else{
					System.out.println("There is no this type");
					return;
				}
		}
		else if(typeReport.contentEquals("console")){
			key = typeReport.concat("_").concat(nameReport);
			if(!getDictReports().containsKey(key)){
				reporterX = new ConsoleReport(nameReport);
			}
			else{
				System.out.println("There is no this type");
				return;
			}
		}
		else{
			System.out.println("addReport:: Type '" + typeReport + "' was not found!");
			return;
		}
   		
   		addElementToDictReports(key, reporterX);
			
    }	

/*    public void newAction(String actionName, String details){
    	report("actionstart", 0, actionName, details, null, null);
    }
    
    public void endAction(){};
    
    public void startStep(String stepName) {
    	report("stepstart", 0, stepName, "", null, null);
    }
    public void startStep(String stepName, String stepDesc){
    	report("stepstart", 0, stepName, stepDesc, null, null);
    } 
    
    public void endStep(String expectedRes){
    	reportEx("stepstart", 0, "", "", expectedRes, null, null);
    }*/
    
/*    *//**
     * @param messageType
     * @param StatusMessage
     * @param header
     * @param fullDescription
     * @param erroId
     * @param objCapture
     *//*
    private void generateMessage(String messageType, Integer statusMessage, String header, String fullDescription, String expectedResult, String erroId, Object objCapture){
   	   	Message msg = new Message(); 
    	setMessage(msg);
    	
    	if (!messageType.contentEquals("actionstart")){
    		String id = generateMsgId();
    		getMessage().setId(id);
    		this.lastId = getMessage().getId();
    	}

    	getMessage().setMessageType(messageType);
    	getMessage().setStatus(statusMessage);
    	getMessage().setHeader(header);
    	getMessage().setDescription(fullDescription);
    	getMessage().setExpected(expectedResult);
    	getMessage().setErrorId(erroId); 
    	
    }*/
    
    private String createSnapshot(int msgID){
    	return "";
    }
    
/*    *//**
     * @return
     *//*
    private String generateMsgId(){
    	Integer i;
    	if(lastId == null){
    		lastId = "0";
    	}
    	
    	i = Integer.parseInt(lastId);
    	i++;
    	return i.toString();
    }*/
    
/*    *//**
     * 
     *//*
    private void clearMessage(){
    	if (getMessage() != null){
    	  	setLastMsgDate(getMessage().getDateTime());
    	  	setMessage(null);
    	}  	
     }
    
    private void RegisterEvent(String msgType, Integer msgStatus){
    	//Todo should be debugged

    	if(msgType.contentEquals("cp")){
    		cpCnt = cpCnt + 1;
    		if ((msgStatus == STATUS_DONE) ||  (msgStatus == STATUS_PASS)){
				cpPassedCnt = cpPassedCnt + 1;
    		}
			else
				cpFailedCnt  = cpFailedCnt + 1;
			
			if (testStatus.contentEquals("Passed") || testStatus.contentEquals("Warning")){
				testStatus = "Failed";
				isTestStatusChanged = true;
    		} 
    	}
    	else if(msgType.contentEquals("event")){
    		if (msgStatus == STATUS_FAIL){
    			errorCnt = errorCnt + 1;
    			if (testStatus.contentEquals("Passed") || testStatus.contentEquals("Warning")){
    				testStatus = "Failed";
    				isTestStatusChanged = true;
    			}
    			else if (msgStatus == STATUS_WARNING){
    				warningCnt = warningCnt + 1;
    				if( testStatus.contentEquals("Passed")){
    					testStatus = "Warning";
    					isTestStatusChanged = true;
    				}
    			}
    		}
    	}

    	else if (msgType.contentEquals("step")){
				stepCnt = stepCnt + 1
				
				Select Case eventStatus

					Case micFail
						stepFailedCnt = stepFailedCnt + 1
						If (testStatus = "Passed") Or (testStatus = "Warning") Then
							testStatus = "Failed"
							isTestStatusChanged = True
						End If
						
					Case micWarning
						stepWarningCnt = stepWarningCnt + 1
						If testStatus = "Passed" Then
							testStatus = "Warning"
							isTestStatusChanged = True
						End If
						
					Case micPass, micDone, micGeneric
							stepPassedCnt = stepPassedCnt + 1
							
					Case Else
						Reporter.ReportEvent micWarning, "Internal error in RegisterEvent", "Unknown event status:" & EmpVL(CStr(eventStatus))
						
				End Select
				

    	}
    	else{
			 System.out.println("Internal error in RegisterEvent. " + "Unknown event type:" + u.empVl(msgType));
		}
		
		//save();
		
    }*/
    
    
}